#include <header.h>
#define MAX 30
#define loops 15

int buffer[MAX];
int fill = 0;
int use	= 0;
int count = 0;

pthread_cond_t empty_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t fill_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;


void put(int value) { 
	buffer[fill] = value; 
	fill = (fill + 1) % MAX; 
	count++; 
} 
int get() { 
	int tmp = buffer[use]; 
	use = (use + 1) % MAX; 
	count--; 
	return tmp; 
} 

void *producer(void *arg) { 
	int i; 
	for (i = 0; i < loops; i++){ 
		// 加锁
		pthread_mutex_lock(&mutex);
		
		while (count == MAX)
			// 缓冲池满，生产者阻塞
			pthread_cond_wait(&empty_cond, &mutex);
		put(i);
		// 生产好了唤醒一个消费者
		pthread_cond_signal(&fill_cond);

		// 解锁
		pthread_mutex_unlock(&mutex);
	} 
}

void *consumer(void *arg) { 
	int i; 
	for (i = 0; i < loops; i++){
		// 加锁
		pthread_mutex_lock(&mutex);

		// 
		while (count == 0)
			// 缓冲池空了，消费者阻塞
			pthread_cond_wait(&fill_cond, &mutex);
		int tmp = get();

		// 消费一个通知生产者
		pthread_cond_signal(&empty_cond);

		// 解锁
		pthread_mutex_unlock(&mutex);
		printf("%d\n", tmp); 
	}
}

int main(int argc, char* argv[]){
	
	pthread_t consumer_id;
	pthread_t producer_id;

	int retp1 = pthread_create(&consumer_id, NULL, consumer, NULL); 
	THREAD_ERROR_CHECK(retp1, "consumer thread create");

	int retp2 = pthread_create(&producer_id, NULL, producer, NULL);
	THREAD_ERROR_CHECK(retp2, "producer thread create");



	int retj2 = pthread_join(producer_id, NULL);
	THREAD_ERROR_CHECK(retj2, "join producer");
	int retj1 = pthread_join(consumer_id, NULL);
	THREAD_ERROR_CHECK(retj1, "join consumer");
	return 0;
}